package org.uma.jmetal.util.comparator.impl;

import org.uma.jmetal.solution.Solution;
import org.uma.jmetal.util.ConstraintHandling;
import org.uma.jmetal.util.comparator.ConstraintViolationComparator;

/**
 * This class implements a <code>Comparator</code> (a method for comparing <code>Solution</code> objects)
 * based on the overall constraint violation of the solutions, as done in NSGA-II.
 *此类实现了<code> Comparator </ code>（一种用于比较<code> Solution </ code>对象的方法）
 *基于NSGA-II中违反解决方案的总体约束。
 *
 * @author Antonio J. Nebro <antonio@lcc.uma.es>
 */
@SuppressWarnings("serial")
public class OverallConstraintViolationComparator<S extends Solution<?>>
    implements ConstraintViolationComparator<S> {
  /**
   * Compares two solutions. If the solutions has no constraints the method return 0
   *
   * @param solution1 Object representing the first <code>Solution</code>.
   * @param solution2 Object representing the second <code>Solution</code>.
   * @return -1 if the overall constraint violation degree of solution1 is higher than the one of solution2, 1 in
   * the opposite case, and 0 if they have the same value (this case applies when the two compared solutions
   * have no constraints). Note that the violation degree is a negative number, so when comparing to two solutions,
   * the higher the value the better.
   *比较两个解决方案。 如果解决方案没有约束，则该方法返回0
   *
   * @param solution1代表第一个<code> Solution </ code>的对象。
   * @param solution2代表第二个<code> Solution </ code>的对象。
   * @return -1，如果solution1的总体约束违反程度高于solution2的约束程度，则为1
   *相反的情况，如果它们具有相同的值，则返回0（在两个比较的解决方案中，此情况适用
   *没有任何限制）。 请注意，违规程度为负数，因此，与两种解决方案进行比较时，
   *值越高越好。
   * /
   */
  @Override
  public int compare(S solution1, S solution2) {
    double violationDegreeSolution1 ;
    double violationDegreeSolution2;

    violationDegreeSolution1 = ConstraintHandling.overallConstraintViolationDegree(solution1);
    violationDegreeSolution2 = ConstraintHandling.overallConstraintViolationDegree(solution2);

    if ((violationDegreeSolution1 < 0) && (violationDegreeSolution2 < 0)) {
      if (violationDegreeSolution1 > violationDegreeSolution2) {
        return -1;
      } else if (violationDegreeSolution2 > violationDegreeSolution1) {
        return 1;
      } else {
        return 0;
      }
    } else if ((violationDegreeSolution1 == 0) && (violationDegreeSolution2 < 0)) {
      return -1;
    } else if ((violationDegreeSolution1 < 0) && (violationDegreeSolution2 == 0)) {
      return 1;
    } else {
      return 0;
    }
  }
}
